跳到主要内容

SpringBoot 启动的钩子函数

启动时初始化资源

参考资料 Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 参考资料 面试官:Spring Boot项目怎么在启动后初始化一些数据?

有下面两种方法

CommandLineRunner

CommandLineRunner 接口的 Component 会在所有 Spring Beans 都初始化之后,SpringApplication.run() 之前执行

例如下面这个初始化 redis 数据的操作

/**
* 启动前先把 mysql 的数据加载到 redis
* 当有多个钩子函数时,通过 @Order 注解
* 来指定其加载次序
*
* @author alsritter
* @version 1.0
**/
@Component
@Slf4j
public class LoadRedisRunner implements CommandLineRunner {

@Resource
StringRedisTemplate stringTemplate;

@Resource
public StudentMapper studentMapper;

@Override
public void run(String... args) throws Exception {
log.info("LoadRedisRunner 开始执行");
// 先检查当前 redis 是否有数据,有就跳过
Set<String> members = stringTemplate.opsForSet().members(ConstantKit.STUDENT_ID_LIST);
if (members != null) {
if (!members.isEmpty()){
members.forEach(o -> log.debug("已存在数据:{}", o));
return;
}
}

log.info("开始加载数据到 redis");
List<String> studentIdList = studentMapper.getStudentIdList();
// 保存到 set 集合上去,避免元素冲突
studentIdList.forEach( o ->{
stringTemplate.opsForSet().add(ConstantKit.STUDENT_ID_LIST, o);
});
stringTemplate.opsForSet().members(ConstantKit.STUDENT_ID_LIST).forEach(o-> log.debug("新增数据:{}", o));
}
}

@PostConstruct 注解

@PostConstruct 注解会在一个类里面的依赖注入完成之后执行

@Service
public class BusinessSercice {
@Autowired
private UserService userService;
private List<String> list = null;
/**
* 构造方法执行之后,调用此方法
*/
@PostConstruct
public void init(){
System.out.println("@PostConstruct方法被调用");
// 实例化类之前缓存获得用户信息
List<String> list = userService.getUser();
this.list = list;
if(list != null && !list.isEmpty()){
for(String user : list){
System.out.println("用户:" + user);
}
}
}
public BusinessSercice(){
System.out.println("构造方法被调用");
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}